/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package session.stateless;

import entity.AddressEntity;
import entity.BranchEntity;
import entity.IndustryTypeEntity;
import entity.OwnerEntity;
import entity.PortalDescriptionLocale;
import entity.StakeholderEntity;
import java.util.List;
import javax.ejb.Stateless;
import javax.ejb.LocalBean;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import exception.ExistException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import javax.ejb.EJB;
import util.entityhelper.StakeholderAccountState;
import util.enumeration.IndustryType;

/**
 *
 * @author Koh Li
 */
@Stateless
@LocalBean
public class StakeholderSessionBeanStateless {

    private String selectedLocale;
    @PersistenceContext
    private EntityManager entityManager;
    private StakeholderAccountState stakeholderAccountState;
    @EJB
    private MessageSessionBean messageSession;
    private SystemMessagesBean systemMessages;

    public StakeholderSessionBeanStateless() {
        systemMessages = new SystemMessagesBean();
    }

    public void setSelectedLocale(String locale) {
        this.selectedLocale = locale;
    }

    //register a new stakeholder
    public void addNewStakeholder(StakeholderEntity stakeholderTemp, IndustryType industryTypeEnum, AddressEntity addressTemp) throws
            ExistException {
        if (checkUsernameExist(stakeholderTemp.getUsername())) {
            throw new ExistException("The username " + stakeholderTemp.getUsername() + " has already existed.");
        }

        if (checkEmailExist(stakeholderTemp.getCorpEmail())) {
            throw new ExistException("The email " + stakeholderTemp.getCorpEmail() + " has already existed.");
        }
        if (checkBizRegNumberExist(stakeholderTemp.getBizRegNumber())) {
            throw new ExistException("The business registration number " + stakeholderTemp.getBizRegNumber() + " has already existed.");
        }
        AddressEntity address = new AddressEntity(addressTemp);
        entityManager.persist(address);


        IndustryTypeEntity industryType = new IndustryTypeEntity();
        industryType.setIndustryType(industryTypeEnum);
        entityManager.persist(industryType);


        StakeholderEntity stakeholder = new StakeholderEntity(stakeholderTemp);
        System.out.println("at session what is the industry" + industryTypeEnum);
        stakeholder.setIndustry(industryType);
        stakeholder.setAddress(address);
        stakeholder.setStakeholderDesc(null);
        stakeholder.setImgUrl(null);

        // auto get system time for registration date
        Calendar cal = Calendar.getInstance();
        Date creationDate = cal.getTime();

        stakeholder.setCreationDate(creationDate);

        entityManager.persist(stakeholder);


        //create  new mailbox for stakeholder
        System.out.println("creating new inbox....");
        OwnerEntity newUser = new OwnerEntity();
        newUser.setName(stakeholder.getUsername());
        newUser.setStaff(false);
        newUser.setTourist(false);
        newUser.setStakeholder(true);
        messageSession.createMailbox(newUser);
    }

    public List<StakeholderEntity> getAllStakeholders() {
        Query query = entityManager.createQuery("SELECT s FROM Stakeholder s");
        return query.getResultList();
    }

    public List<StakeholderAccountState> getAllStakeholdersByStakeholderAccountState() throws ExistException {
        Query query = entityManager.createQuery("SELECT s FROM Stakeholder s");
        List stateList = new ArrayList();

        if (query.getResultList().isEmpty()) {
            throw new ExistException(systemMessages.getSystemMessage("STAKEHOLDER_ACCTS_DO_NOT_EXIST", selectedLocale));
        } else {
            for (Object o : query.getResultList()) {
                StakeholderEntity s = (StakeholderEntity) o;
                StakeholderAccountState stakeholderAcctState = new StakeholderAccountState(
                        s.getId(),
                        s.getBizRegNumber(),
                        s.getCorpName(),
                        s.getCorpContactNumber(),
                        s.getCorpContactPerson(),
                        s.getCorpEmail(),
                        s.getCorpFaxNumber(),
                        s.getShortDesc(),
                        s.getActivate(),
                        s.getImgUrl(),
                        s.getStakeholderDesc(),
                        s.getIndustry(),
                        s.getAddress(),
                        s.getBranches(),
                        s.getDescLocale(),
                        s.getMedia());
                stateList.add(stakeholderAcctState);
            }
        }
        return stateList;
    }

    public void editStakeholderInfo(StakeholderEntity stakeholder) {
        entityManager.merge(stakeholder);
    }

    private boolean checkUsernameExist(String username) {
        Query query = entityManager.createQuery("SELECT s FROM Stakeholder s WHERE s.username = :username");
        query.setParameter("username", username);
        List list = query.getResultList();

        if (list.isEmpty()) {
            return false;
        }

        return true;
    }

    private boolean checkEmailExist(String email) {
        Query query = entityManager.createQuery("SELECT s FROM Stakeholder s WHERE s.corpEmail = :email");
        query.setParameter("email", email);
        List list = query.getResultList();

        if (list.isEmpty()) {
            return false;
        }

        return true;
    }

    private boolean checkBizRegNumberExist(String bizRegNumber) {
        Query query = entityManager.createQuery("SELECT s FROM Stakeholder s WHERE s.bizRegNumber = :bizRegNumber");
        query.setParameter("bizRegNumber", bizRegNumber);
        List list = query.getResultList();

        if (list.isEmpty()) {
            return false;
        }

        return true;
    }

    //get the list of available localse under stakeholder. 
    public List<PortalDescriptionLocale> getStakeholderLocaleDetail(Long stakeholderId) {

        Query q = entityManager.createQuery("SELECT l FROM PortalDescriptionLocale l WHERE l.stakeholder.id = :userid");
        q.setParameter("userid", stakeholderId);
        return q.getResultList();

    }

    public StakeholderEntity retrieveStakeholderInfoByUsername(String username) {
        Query query = entityManager.createQuery("SELECT s FROM Stakeholder s WHERE s.username = :username");
        query.setParameter("username", username);
        return (StakeholderEntity) query.getSingleResult();
    }

    public StakeholderAccountState getStakeholderPortalInfoById(Long stakeholderId)
            throws ExistException {
        System.out.println("Stakedolder id in session bean: " + stakeholderId);
        Query q = entityManager.createQuery("SELECT s FROM Stakeholder s WHERE s.id = :accId");
        q.setParameter("accId", stakeholderId);

        if (q.getResultList().isEmpty()) {
            // might have to move this elsewhere....
            // EXCEPTION

            throw new ExistException("SOMETHING IS WRONG; Please Login again");

        } else {
            System.out.println("Stakeholder exist");
            StakeholderEntity stakeholder = (StakeholderEntity) q.getSingleResult();
            setStakeholderAccountState(new StakeholderAccountState(stakeholder.getId(),
                    stakeholder.getUsername(),
                    stakeholder.getStakeholderDesc(),
                    stakeholder.getImgUrl(),
                    stakeholder.getCorpName()));
        }

        return stakeholderAccountState;
    }

    public StakeholderAccountState getStakeholderByUsername(String stakeholderUsername) throws ExistException {
        //StakeholderAccountState stakeholderAccountState = null;
        //System.out.println("userName at backend: " +stakeholderUsername.trim());

        // find account id
        Query q = entityManager.createQuery("SELECT s FROM Stakeholder s WHERE s.username = :accName");
        q.setParameter("accName", stakeholderUsername.trim());

        if (q.getResultList().isEmpty()) {
            // EXCEPTION
            throw new ExistException("STAKEHOLDER_ACCT_DOES_NOT_EXIST");

        } else {
            //  System.out.println("Stakeholder exist");
            // auto get system time for registration date
            Calendar cal = Calendar.getInstance();
            Date loginTime = cal.getTime();

            StakeholderEntity stakeholder = (StakeholderEntity) q.getSingleResult();
            //to update login date; 

            setStakeholderAccountState(new StakeholderAccountState(
                    stakeholder.getId(),
                    stakeholder.getUsername(),
                    stakeholder.getPassword(),
                    stakeholder.getCorpEmail(),
                    stakeholder.getBizRegNumber(),
                    stakeholder.getActivate(),
                    loginTime));
        }
        return getStakeholderAccountState();
    }//end of method getStakeholder by ID

    public StakeholderEntity getStakeholderById(Long stakeholderId) throws ExistException {

        Query query = entityManager.createQuery("SELECT s FROM Stakeholder s WHERE s.id = :accId");
        query.setParameter("accId", stakeholderId);
        if (query.getResultList().isEmpty()) {
            // EXCEPTION
            System.out.println("stakeholder dont exist!");
            throw new ExistException("STAKEHOLDER_ACCT_DOES_NOT_EXIST");
        }
        return (StakeholderEntity) query.getSingleResult();
    }

    public StakeholderAccountState getPortalDetail(Long stakeholderId) throws ExistException {
        stakeholderAccountState = getStakeholderPortalInfoById(stakeholderId);
        stakeholderAccountState.setBranches(viewBranchOutlet(stakeholderId));

        return getStakeholderAccountState();
    }

    public boolean addPortalInfoByInfo(StakeholderAccountState stakeholderAcc) throws ExistException {
        boolean success = false;

        StakeholderEntity stakeholder = entityManager.find(StakeholderEntity.class, stakeholderAcc.getId());
        if (stakeholder == null) {

            return false;
        }
        System.out.println("Stakeholder Desc at backend: " + stakeholderAcc.getStakeholderDesc());
        stakeholder.setStakeholderDesc(stakeholderAcc.getStakeholderDesc());
        stakeholder.setImgUrl(stakeholderAcc.getImgUrl());
        success = true;

        return success;
    }

    public boolean addLocalePortal(StakeholderAccountState stakeholderAcc) throws ExistException {
        boolean success = false;

        StakeholderEntity stakeholder = entityManager.find(StakeholderEntity.class, stakeholderAcc.getId());
        if (stakeholder == null) {
            return false;
        }
        System.out.println("successful find stakeholder");
        PortalDescriptionLocale locale = new PortalDescriptionLocale();
        int size = stakeholderAcc.getLocaleDesc().size();
        for (int i = 0; i < size; i++) {
            locale = stakeholderAccountState.getLocaleDesc().get(i);
            locale.setStakeholder(stakeholder);
            entityManager.persist(locale);
        }
        //stakeholder.setDescLocale(stakeholderAcc.getLocaleDesc());
        //System.out.println("stakeholder localse size: " +stakeholderAcc.getLocaleDesc().size());
        System.out.println("saving new lanugage...");

        //entityManager.persist(stakeholderAcc.getLocaleDesc());

        //entityManager.persist(stakeholder);

        success = true;

        return success;
    }

    public List<BranchEntity> viewBranchOutlet(Long stakeholderId) {
        Query query = entityManager.createQuery("SELECT b FROM Branch b WHERE b.stakeholder.id =:sid");
        query.setParameter("sid", stakeholderId);
        System.out.println("at backend: managed to get branch " + query.getResultList().size());
        return query.getResultList();
    }

    /*
     * @return the stakeholderAccountState
     */
    public StakeholderAccountState getStakeholderAccountState() {
        return stakeholderAccountState;
    }

    /**
     * @param stakeholderAccountState the stakeholderAccountState to set
     */
    public void setStakeholderAccountState(StakeholderAccountState stakeholderAccountState) {
        this.stakeholderAccountState = stakeholderAccountState;
    }

    /**
     * @return the messageSession
     */
    public MessageSessionBean getMessageSession() {
        return messageSession;
    }

    /**
     * @param messageSession the messageSession to set
     */
    public void setMessageSession(MessageSessionBean messageSession) {
        this.messageSession = messageSession;
    }
}
